#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMenu>
#include <QIcon>
#include <QAction>
#include <QMapIterator>
#include <QLabel>
#include <QToolButton>
#include <QDebug>

#include "dda.h"
#include "brezenhem.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/resources/qtlogo.jpg"));


    createAlgorithms();
    createToolBox();
    createCentralWidget();
    createActions();
    createToolBar();

    mTimer = new QTimer();
    connect(mTimer, SIGNAL(timeout()), mScene, SLOT(drawNext()));
    connect(mScene, SIGNAL(drawed()), this, SLOT(stopTimer()));

    resize(800, 600);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::createAlgorithms(){
    mAlgs.insert("Lines", new DDA());
    mAlgs.insert("Lines", new Brezenhem());
}

void MainWindow::createActions(){
    QAction* clearAction = new QAction("Clear", this);
    clearAction->setShortcut(QKeySequence("Ctrl+d"));
    this->addAction(clearAction);
    connect(clearAction, SIGNAL(triggered()), mScene, SLOT(clear()));

    mNextStep = new QAction(QIcon(":/resources/next.png"), "Next", this);
    connect(mNextStep, SIGNAL(triggered()), mScene, SLOT(drawNext()));

    mDrawBySteps = new QAction(QIcon(":/resources/play.png"), "Play", this);
    connect(mDrawBySteps, SIGNAL(triggered()), this, SLOT(startTimer()));
}

void MainWindow::startTimer(){
    if (mScene->isInDebug())
        mTimer->start(50);
}

void MainWindow::stopTimer(){
    mTimer->stop();
}

void MainWindow::createToolBar(){
    mToolBar = new QToolBar;
    QToolButton* debugButton = new QToolButton;
    debugButton->setIcon(QIcon(":/resources/debug1.jpg"));

    debugButton->setCheckable(true);
    connect(debugButton, SIGNAL(clicked()), mScene, SLOT(toDebug()));

    mToolBar->addWidget(debugButton);
    mToolBar->addAction(mNextStep);
    mToolBar->addAction(mDrawBySteps);
    addToolBar(mToolBar);
}

void MainWindow::resizeEvent(QResizeEvent *e){
    QMainWindow::resizeEvent(e);
    if (!mScene->sceneRect().contains(rect()))
        mScene->setSceneRect(rect());
}

void MainWindow::createCentralWidget(){
    mCentralWidget = new QWidget();
    mScene = new Scene();
    QRectF sceneRect = rect();
    mScene->setSceneRect(sceneRect);
    mView = new QGraphicsView();
    mView->setMouseTracking(true);
    mView->fitInView(sceneRect, Qt::KeepAspectRatio);

    mView->setScene(mScene);

    QHBoxLayout* centralWidgetLayout = new QHBoxLayout();
    centralWidgetLayout->addWidget(mToolBox);
    centralWidgetLayout->addWidget(mView);

    mCentralWidget->setLayout(centralWidgetLayout);
    setCentralWidget(mCentralWidget);
}

void MainWindow::createToolBox(){
    mToolBox = new QToolBox;
    mButtonGroup = new QButtonGroup;
    mButtonGroup->setExclusive(false);

    foreach(QString key, mAlgs.uniqueKeys()){
        QVBoxLayout* layout = new QVBoxLayout;
        QWidget* widget = new QWidget;
        foreach(Algorithm* alg, mAlgs.values(key)){
            QToolButton* button = new QToolButton;
            button->setText(alg->name());
            button->setCheckable(true);
            button->setMinimumWidth(90);
            button->setMaximumWidth(90);
            mButtonGroup->addButton(button);
            layout->addWidget(button);
        }
        layout->addStretch();
        widget->setLayout(layout);
        mToolBox->addItem(widget, key);
    }
    connect(mButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(algorithmChecked(int)));
    mToolBox->setMinimumWidth(110);
    mToolBox->setMaximumWidth(110);

}

void MainWindow::algorithmChecked(int buttonId){
    foreach(QAbstractButton* button, mButtonGroup->buttons()){
        if(mButtonGroup->button(buttonId) != button)
            button->setChecked(false);
    }
    QAbstractButton* checkedButton = mButtonGroup->checkedButton();
    QString index = mToolBox->itemText(mToolBox->indexOf(mToolBox->currentWidget()));
    if (checkedButton){
        QString name = checkedButton->text();
        Algorithm* alg = 0;
        foreach(Algorithm* _alg, mAlgs.values(index)){
            if (_alg->name() == name){
                alg = _alg;
                break;
            }
        }
        mScene->setAlg(alg);
    }
}
